
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BFile>
#include <BEntry>
#include <BXmlDocument>
#include <BStyle>
#include <BSystem>
#include <BApplication>

#include "HistoryDialog.h"

HistoryDialog::HistoryDialog(BWidget* parent) : BDialog(parent)
{
	this->setTitle("History");
	this->setFrameless(true);

	_listWidget = new BListWidget();
	_listWidget->setAreaPolicy(Policy_Dynamic);
	{
		_removeButton = new BButton(Graph_Cross, _listWidget);
		_removeButton->hide();
	}

	BHBoxLayout* bottomLayout = new BHBoxLayout("button-layout");
	{
		_quitButton = new BButton("Quit");
		_openButton = new BButton("Open");
		_openButton->setEnabled(false);
		_cancelButton = new BButton("Cancel");
		bottomLayout->addWidget(_quitButton);
		bottomLayout->addSpring(10);
		bottomLayout->addWidget(_openButton);
		bottomLayout->addWidget(_cancelButton);
	}

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addWidget(_listWidget);
	vlayout->addLayout(bottomLayout, 0);

	connect("raise-item", &HistoryDialog::slotRaiseItemOfText);

	connect(_removeButton, Signal_Clicked, &HistoryDialog::slotRemoveButtonClicked);
	connect(_listWidget, Signal_ItemSelected, &HistoryDialog::slotListItemSelected);
	connect(_listWidget, Signal_ItemDoubleClicked, &HistoryDialog::slotListItemDoubleClicked);
	connect(_listWidget, Signal_Resized, &HistoryDialog::slotListWidgetResized);
	connect(_quitButton, Signal_Clicked, &HistoryDialog::slotQuitButtonClicked);
	connect(_openButton, Signal_Clicked, &HistoryDialog::slotOpenButtonClicked);
	connect(_cancelButton, Signal_Clicked, &HistoryDialog::slotCancelButtonClicked);

	_fileName = BApplication::homePath();
	BString appName = BString(BApplication::argv(0)).name();
	appName -= appName.dext();
	_fileName << '/' << appName << "/histories.xml";

	BXmlDocument xmldoc;
	if (BXmlNode* root = xmldoc.load(_fileName))
	{
		_listWidget->clearItems();
		for (int i = 0; i < root->childCount(); i++)
		{
			BXmlNode* child = root->child(i);
			const BString& fileStr = child->attrib("file");
			const BString& dateStr = child->attrib("date");
			const BString& timeStr = child->attrib("time");
			BString text = fileStr.name();
			text += '\n';
			text += fileStr;
			BListItem* item = new BListItem(text);
			item->setAsset(fileStr);
			item->setProperty("date", BDate(dateStr));
			item->setProperty("time", BTime(timeStr));
			item->setIcon(BSystem::EntryIcon(fileStr));
			_listWidget->addItem(item);
		}
	}

}
HistoryDialog::~HistoryDialog()
{
	if (_listWidget->property("dirty"))
	{
		BXmlNode* historyNode = new BXmlNode("history");
		{
			for (int i = 0; i < _listWidget->itemCount(); i++)
			{
				BListItem* item = _listWidget->item(i);
				BDate date = item->property("date");
				BTime time = item->property("time");
				BXmlNode* node = new BXmlNode("resource");
				node->setAttrib("file", item->asset());
				node->setAttrib("date", date.toString());
				node->setAttrib("time", time.toString());
				historyNode->addChild(node);
			}
		}
		if (!BFile::Exist(_fileName))
			BFile::Create(_fileName);
		BXmlDocument xmldoc;
		xmldoc.setFormat("\n<>\n</>");
		xmldoc.save(_fileName, historyNode);
	}
}

bool HistoryDialog::empty() const
{
	return _listWidget->itemCount() == 0;
}

void HistoryDialog::slotRaiseItemOfText(BObject* object, const BValue& value)
{
	const BString& fileStr = value;
	for (int i = 0; i < _listWidget->itemCount(); i++)
	{
		BListItem* item = _listWidget->item(i);
		const BString& text = item->asset();
		if (text == fileStr)
		{
			item->raise();
			_listWidget->setProperty("dirty", true);
			return;
		}
	}
	BString text = fileStr.name();
	text += '\n';
	text += fileStr;
	BListItem* item = new BListItem(text);
	item->setAsset(fileStr);
	item->setProperty("date", BSystem::LocalDate());
	item->setProperty("time", BSystem::LocalTime());
	_listWidget->insertItem(0, item);
	_listWidget->setProperty("dirty", true);
}
void HistoryDialog::slotRemoveButtonClicked(BObject* object, const BValue& value)
{
	if (BListItem* item = object->asset())
	{
		if (_listWidget->removeItem(item))
		{
			_listWidget->setProperty("dirty", true);
		}
	}
}
void HistoryDialog::slotListItemSelected(BObject* object, const BValue& value)
{
	BListItem* item = value;
	if (item->selected())
	{
		BSize hsize = _removeButton->sizeHint();
		const BRect& crect = _listWidget->centerRect();
		BRect itemRect = item->rect();
		itemRect.left() = crect.left();
		itemRect.right() = crect.right();
		BRect rect = itemRect.align(Align_RightCenter, hsize);
		_removeButton->setRect(rect);
		_removeButton->setVisible(true);
		_removeButton->setAsset(value);
		this->setProperty("file", item->asset());
		_openButton->setEnabled(true);
	}
	else
	{
		_removeButton->setVisible(false);
		_removeButton->setAsset(BValue());
		this->setProperty("file", BValue());
		_openButton->setEnabled(false);
	}
}
void HistoryDialog::slotListItemDoubleClicked(BObject* object, const BValue& value)
{
	this->close(Button_Open);
}
void HistoryDialog::slotQuitButtonClicked(BObject* object, const BValue& value)
{
	this->setProperty("file", BValue());
	this->close(Button_None);
}
void HistoryDialog::slotOpenButtonClicked(BObject* object, const BValue& value)
{
	this->close(Button_Open);
}
void HistoryDialog::slotCancelButtonClicked(BObject* object, const BValue& value)
{
	this->close(Button_Cancel);
}
void HistoryDialog::slotListWidgetResized(BObject* object, const BValue& value)
{
	if (BListItem* item = _removeButton->asset())
	{
		BSize hsize = _removeButton->sizeHint();
		const BRect& crect = _listWidget->centerRect();
		BRect itemRect = item->rect();
		itemRect.left() = crect.left();
		itemRect.right() = crect.right();
		BRect rect = itemRect.align(Align_RightCenter, hsize);
		_removeButton->setRect(rect);
	}
}

void HistoryDialog::showEvent(const BEvent& event)
{
	BDialog::showEvent(event);
}

void HistoryDialog::styleEvent(const BEvent& event)
{
	BDialog::styleEvent(event);
	const BStyle* style = event.value();
	_removeButton->setIcon(style->icon("remove"));
}
